package com.goodboys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.goodboys.bean.ArticleDetailBean;
import com.goodboys.bean.ArticleListBean;
import com.goodboys.bean.BaseParamBean;
import com.goodboys.service.IDataService;
import com.goodboys.utils.JedisUtil;
import com.goodboys.utils.JsoupUtils;
import org.jsoup.Connection;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.io.IOException;
import java.util.*;

/**
 * Created by CJ on 2018-03-29.
 */
@Service("iDataSevice")
public class IDataServiceImpl implements IDataService{

    private final Logger logger = LoggerFactory.getLogger(IDataServiceImpl.class);

    @Value("${api.app_id}")
    private String appid;

    @Value("${api.access_token}")
    private String token;

    //获取查询列表
    @Override
    public Map<String,Object> getArticleList(BaseParamBean param) {
        Map<String,Object> result=null;
        String message = null;
        String url = null;
        if(param != null) {
            result =  new HashMap<>();
            //获取链接https://api.cn-ki.net/openapi/search?keyword=springboot&db=SCDB&app_id=test&access_token=test&sort_type=1
            url = "https://api.cn-ki.net/openapi/search?app_id="+appid+"&access_token="+token
                    +"&keyword="+param.getKeyword()+"&db="+param.getDb()+"&start="+param.getStart()
                    +"&advance="+param.getAdvance();
            //获取源码
            try {
                String html = JsoupUtils.getHtml(url);
                if (html == null) {
                    result.put("message", "查询失败，请重试。。。");
                    result.put("status", 0);
                    return result;
                }
                JSONObject jsonObject = JSON.parseObject(html);
                Integer status = jsonObject.getInteger("status");
                if (status != null && status == 0) {
                    //获取列表失败
                    message = jsonObject.getString("message");
                    logger.error(message);
                    result.put("status", status);
                    result.put("message", "解析列表源码错误！");
                } else {
                    JSONObject data = jsonObject.getJSONObject("data");
                    String start = data.getString("start");
                    Integer total = data.getInteger("total_count");
                    JSONArray items = data.getJSONArray("items");
                    Map map = new HashMap();
                    if (items.size() > 0) {
                        List<ArticleListBean> listBeans = JSON.parseObject(items.toJSONString(), new TypeReference<List<ArticleListBean>>() {
                        });
                        //更改镜像地址,将下载、预览链接关闭
                        listBeans.forEach(articleListBean -> {
                            articleListBean.setMirrorUrl((articleListBean.getMirrorUrl() != null) ? articleListBean.getMirrorUrl().replace("cnki.cn-ki.net", "kns.cnki.net") : "");
                            //更改详情页地址内容
                            articleListBean.setUrl((articleListBean.getUrl() != null) ? articleListBean.getUrl().replaceFirst("/doc_detail","/detail") : "");
                        });
                        map.put("items", listBeans);
                    }
                    map.put("start", start);
                    map.put("total", total);
                    result.put("data", map);
                    result.put("status", status);
                }
            } catch (IOException e) {
                //源码拿去错误
                logger.warn("源码下载错误！"+url);
                e.printStackTrace();
            }

        }
        return result;
    }


    //获取文章详情
    @Override
    public  Map<String,Object> getArticleDetail(BaseParamBean param) {
        Map<String,Object> result = null;
        //获取文章返回的json
        String message = null;

        //先查看mongodb中是够存在记录

        //mongodb中没有
        String url = null;
        if(param != null) {
            result = new HashMap<>();
            //获取详情链接https://api.cn-ki.net/openapi/doc_detail?dbcode=CJFQ&filename=LQXJ201001014&app_id=756629946&access_token=T1daKB5nS0MoqHkj
            url = "https://api.cn-ki.net/openapi/doc_detail?dbcode="+param.getDbcode()+
                    "&filename="+param.getFilename()+"&app_id="+appid+"&access_token="+token;
            //获取源码
            try {
                String html = JsoupUtils.getHtml(url);
                if(html.isEmpty()){
                    result.put("message","查询详情失败，请重试。。。");
                    result.put("status", 0);
                    return result;
                }
                JSONObject jsonObject = JSON.parseObject(html);
                if(jsonObject.isEmpty()) return null;
                Integer status = jsonObject.getInteger("status");
                if(status != null && status == 0){
                    //获取列表失败
                    message = jsonObject.getString("message");
                    logger.error("获取文章相切报错-----"+message);
                    result.put("message", message);
                }else {
                    JSONObject data = jsonObject.getJSONObject("data");
                    //获取ArticleDetail对象
                    ArticleDetailBean articleDetailBean = JSON.parseObject(jsonObject.getJSONObject("data").toJSONString(), new TypeReference<ArticleDetailBean>() {});
                    //获取文章的下载，预览链接https://api.cn-ki.net//openapi/get_durl?filename=JSYJ2018020800P&filename_en=5gTbM5WT5R1MHFmeQVnVMN3QBd2VKVXe3IVUwZUTzV2dEBXWy1GNyMkS29mdZd2aLlzRJdVT0t0ZK10QwJTaR9mYaZnZ6dkWaB1aDJXQupXRkNzYr5GcHZjZvMmck9GZKdVYnBXa2pnUDRkR2RTeOxkUktEVMZkS&title=%E5%9F%BA%E4%BA%8E%E8%87%AA%E5%8A%A8%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E6%B5%81%E7%A8%8B%E4%BC%98%E5%8C%96%E7%9A%84%E9%9B%B7%E8%BE%BE%E8%BE%90%E5%B0%84%E6%BA%90%E4%BF%A1%E5%8F%B7%E8%AF%86%E5%88%AB&author=%E6%B6%82%E5%90%8C%E7%8F%A9;%20%E9%87%91%E7%82%9C%E4%B8%9C%EF%BC%8C&tablename=CAPJLAST&app_id=8995d40d&access_token=V9ilopkrz1Jmqnw0
                    url = "https://api.cn-ki.net//openapi/get_durl?filename="+param.getFilename()
                            +"&filename_en="+articleDetailBean.getFilenameEn()
                            +"&title="+articleDetailBean.getTitle()
                            +"&author="+articleDetailBean.getAuthor()
                            +"&tablename="+articleDetailBean.getTablename()
                            +"&app_id="+appid+"&access_token="+token;
                    articleDetailBean = getUrlByDownAndPre(url,articleDetailBean);
                    result.put("data", articleDetailBean);
                    result.put("status", status);
                }
            } catch (Exception e) {
                logger.error("返回的列表页解析失败！"+url);
                e.printStackTrace();
            }
        }
        return result;
    }



    //获取文章下载，预览链接
    public ArticleDetailBean getUrlByDownAndPre(String url,ArticleDetailBean articleDetailBean){
        try {
            String html = JsoupUtils.getHtml(url);
            //判断是否
            if (html.isEmpty()) {
                logger.error("获取下载链接1失败！");
                return articleDetailBean;
            } else {
                JSONObject data = JSON.parseObject(html).getJSONObject("data");
                if (data.isEmpty()) return articleDetailBean;
                articleDetailBean.setPdf(data.getBoolean("is_pdf"));
                url = data.getString("url");
                url = url.split("\\?")[1];
                //获取下载链接
                articleDetailBean.setDownUrl("/download?" + url);
                if (articleDetailBean.isPdf()) {
                    //获取文章预览链接
                    articleDetailBean.setPreviewUrl("/preview?" + url);
                }
            }
        } catch (IOException e) {
            logger.warn("下载链接获取失败"+url);
            e.printStackTrace();
            return  null;
        }
        return articleDetailBean;
    }


    /**
     * 获取下载链接
     * @param targetKey
     *          下载秘钥
     * @return
     *          下载链接
     */
    public String getDownloadUrl(String targetKey){
        try {
            Document document = JsoupUtils.getDocument("http://cnki.cn-ki.net/idata_down?targetk=" + targetKey);
            //获取下载链接
            return document.selectFirst("a.btn.btn-block.btn-success").attr("href");
        } catch (Exception e) {
            logger.info("下载错误");
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取预览链接
     * @param targetKey
     *          预览，下载链接
     * @return
     *          预览链接
     */
    public String getPreviewUrl(String targetKey){
        try {
            Document document = JsoupUtils.getDocument("http://cnki.cn-ki.net/idata_down?targetk="+targetKey);
            return document.selectFirst("a.btn.btn-block.btn-info").attr("href");
        } catch (Exception e) {
            logger.info("下载错误--->  http://cnki.cn-ki.net/idata_down?targetk="+targetKey);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据单个热词从redis中获取热词的查询列表
     * @param hotWord
     * @return
     */
    public Object getArticleListByHotWord(String hotWord){
        Object result = null;
        Jedis jedis = JedisUtil.getJedis();
        try {
            if (hotWord != null) {
                Boolean hotWords = jedis.hexists("hotWords", hotWord);
                if(hotWords){
                    String articleList= JedisUtil.getJedis().hget("hotWords", hotWord);
                    result = JSON.parse(articleList);
                }
            }
        }catch (Exception e){
            logger.info("------------>"+"根据单个热词从redis中获取热词的查询列表");
            e.printStackTrace();
        }finally {
            if(jedis!=null) {
                jedis.close();
                if(jedis.isConnected()) jedis.disconnect();
            }
        }

        return result;
    }

    /**
     * 从redis中获取热词列表
     * @return
     */
    public Map getHotWordsList(){
        Map<String, Object> map = new HashMap<>();
        Integer status = 0;
        Jedis jedis = JedisUtil.getJedis();
        try {
            Set<String> hotWords = jedis.hkeys("hotWords");
            map.put("list", hotWords);
            map.put("status", 1);
            return map;
        } catch (Exception e) {
            map.put("message", "获取结果失败。。。,请稍后继续。");
            map.put("status", 0);
            return map;
        }finally {
            if (jedis != null) {
                jedis.close();
                if(jedis.isConnected()) jedis.disconnect();
            }
        }


    }



   /**
     * 获取知网/万方原始热词并存入redis中
     * @return
    **/
    public List<String> getHotWords(){
        String url = "http://search.cnki.net/sug/topk.ashx?jsonvar=top_Words_Json";
        List<String> strings = new ArrayList<>();
        try {
            String referer = JsoupUtils.getConnection(url)
                    .header("Referer", "http://www.cnki.net/")
                    .execute().body();
            String s = referer.split("=")[1];
            s = s.replace(';', ' ');
            strings= JSON.parseArray(s, String.class);

            //开始获取万方的热词
            url = "http://www.wanfangdata.com.cn/hotTheme.do";
            referer  = JsoupUtils.getConnection(url)
                    .method(Connection.Method.POST)
                    .execute().body();
            List<String> finalStrings = strings;
            JSON.parseArray(referer).parallelStream().forEach(a -> {
                String name =  ((JSONObject) a).getString("name");
                finalStrings.add(name.replaceAll("\\n",""));
            });
            return strings;
        } catch (IOException e) {
            logger.warn("获取热词失败！--》http://search.cnki.net/sug/topk.ashx?jsonvar=top_Words_Json");
            e.printStackTrace();
            return strings;
        }
    }

}
